#include "stdafx.h"
#include "./glTrace.h"

#include <strsafe.h>
#include <assert.h>
namespace GLES
{
#pragma warning(disable:4996)

#if defined(_XTRACE_LOGFILE)
	static HANDLE _xlogfp;
	static AChar _xlogfile[MAX_PATH];
	class xCLog
	{
	public:
		xCLog(void);
		xCLog(Uns32 dirlen,const AChar* dir);
		xCLog(Uns32 dirlen,const WChar* dir);
		~xCLog(void);
	};
	xCLog::xCLog(void)
	{
		StringCchCatA(_xlogfile,MAX_PATH-1,("debug.txt"));
		/*_xlogfp=fopen(_xlogfile,"w");*/
		_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
		xAssertA(_xlogfp!=vNull && "Can't open debug.txt");
	}
	xCLog::xCLog(Uns32 dirlen,const AChar* dir)
	{
		xAssertA(dirlen>MAX_PATH && ("Debug dir too long"));
		StringCchCatA(_xlogfile,dirlen,dir);
		//_xlogfp=fopen(_xlogfile,"w");
		_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
		xAssertA(_xlogfp!=vNull && ("Can't open debug.txt"));
	}
	xCLog::~xCLog(void)
	{
		//fclose(_xlogfp);
		if(_xlogfp != vNull)
			CloseHandle(_xlogfp);
	}
	static xCLog _xlog;
	void xLog(const AChar* pFmt,...)
	{
		AChar sz[512];
		va_list va;
		va_start(va,pFmt);
		StringCchVPrintfA(sz,sizeof(sz),pFmt,va);
		va_end(va);

		_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
		if(_xlogfp != vNull)
		{
			//fwrite(sz,strlen(sz),1,_xlogfp);
			TUint32 written;
			WriteFile(_xlogfp,sz,(Uns32)strlen(sz),&written,vNull);
			CloseHandle(_xlogfp);
		}
	}
#else
	void xLog(const Char* pFmt,...){}
#endif
	//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_OUTCONSOLE)
	static HANDLE _xhcon;
	class xCOut
	{
	public:
		xCOut(void);
		~xCOut(void);
	};
	xCOut::xCOut(void)
	{
		AllocConsole();
		_xhcon=GetStdHandle(STD_OUTPUT_HANDLE);
		xAssertA(_xhcon!=INVALID_HANDLE_VALUE&&"Can't open console");
	}
	xCOut::~xCOut(void)
	{
		CloseHandle(_xhcon);  
		FreeConsole();     
	}
	static xCOut _xcout;
	void xOut(const Char* pFmt,...)
	{
		Char sz[512];
		va_list va;
		va_start(va, pFmt);
		StringCchVPrintf(sz,sizeof(sz),pFmt,va);
		va_end(va);
		Uns32 cWritten;
		if(_xhcon!=INVALID_HANDLE_VALUE)
		{
			WriteConsole(_xhcon, sz, (Uns32)skyStrlen(sz), &cWritten, vNull);
		}
	}
#else
	void xOut(const Char* pFmt,...){}
#endif
	//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_DBGCONSOLE)
	void xDbg(const Char *pFormat,...)
	{
		Char sz[512];
		va_list va;
		va_start(va,pFormat);
		StringCchVPrintf(sz,sizeof(sz),pFormat,va);
		va_end(va);
		OutputDebugString( sz );
	}
#endif
	//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_MSGBOX)
	Void xMessageBox(const Char* pFmt,...)
	{
		Char sz[512];
		va_list va;
		va_start(va,pFmt);
		StringCchVPrintf(sz,sizeof(sz),pFmt,va);
		va_end(va);
		MessageBox(vNull,sz,_XT("xMessageBox"),MB_OK);
	}
#else
	Void xMessageBox(const Char* pFmt,...){}
#endif
	//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE)
	Void doTraceW(xTraceType type,const WChar* sz)
	{
#if defined(_XTRACE_OUTCONSOLE)
		if((type & eType_OutConsol) != 0)
		{
			Uns32 cWritten;
			if(_xhcon!=INVALID_HANDLE_VALUE)
			{
				::WriteConsoleW(_xhcon, sz, (Uns32)wcslen(sz), &cWritten, vNull);
			}
		} // if((type & xOutConsol) != 0)
#endif
#if defined(_XTRACE_DBGCONSOLE)
		if((type & eType_DbgConsol) != 0)
		{
			::OutputDebugStringW( sz );
		}
#endif
#if defined(_XTRACE_LOGFILE)
		if((type & eType_LogFile) != 0)
		{
			HANDLE file;
			file = CreateFileA(("trace.txt"),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			if(file != INVALID_HANDLE_VALUE)
			{
				//fwrite(sz,strlen(sz),1,_xlogfp);
				Uns32 written;
				::WriteFile(file,sz,(Uns32)wcslen(sz),&written,vNull);
				::CloseHandle(file);
			} // if(file != INVALID_HANDLE_VALUE)
		} // if((type & xTraceType::xLogFile) != 0)
#endif
#if defined(_XTRACE_MSGBOX)
		if((type & eType_MsgBox) != 0)
		{ 
			MessageBoxW(vNull,sz,L"trace",MB_OK);
		}
#endif
#if defined(_XTRACE_ASSERT)
		if((type & eType_DxAssert) != 0)
		{
#ifdef D3D9_INCLUDE
			DXTraceW(NULL,0,0,sz,vTrue);
#endif

		}
		else if((type & eType_AssertBox) != 0)
		{
			assert(0&&(char*)sz);
		}

#endif
		return ;
	}
	// MByteToWChar(szA,szW,sizeof(szW)/sizeof(szW[0]));
	//---------------------------------------------------------------------------------------
	BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)
	{
		// Get the required size of the buffer that receives the Unicode 
		// string. 
		DWORD dwMinSize;
		dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);

		if(dwSize < dwMinSize)
		{
			return FALSE;
		}


		// Convert headers from ASCII to Unicode.
		MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);  
		return TRUE;
	}

	//-------------------------------------------------------------------------------------
	//Description:
	// This function maps a wide-character string to a new character string
	//
	//Parameters:
	// lpcwszStr: [in] Pointer to the character string to be converted 
	// lpszStr: [out] Pointer to a buffer that receives the translated string. 
	// dwSize: [in] Size of the buffer
	//
	//Return Values:
	// TRUE: Succeed
	// FALSE: Failed
	// 
	//Example:
	// MByteToWChar(szW,szA,sizeof(szA)/sizeof(szA[0]));
	//---------------------------------------------------------------------------------------
	BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)
	{
		DWORD dwMinSize;
		dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);
		if(dwSize < dwMinSize)
		{
			return FALSE;
		}
		WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);
		return TRUE;
	}
	Void doTraceA(xTraceType type,const AChar* sz)
	{
#if defined(_XTRACE_OUTCONSOLE)
		if((type & eType_OutConsol) != 0)
		{
			Uns32 cWritten;
			if(_xhcon!=INVALID_HANDLE_VALUE)
			{
				::WriteConsoleA(_xhcon, sz, (Uns32)strlen(sz), &cWritten, vNull);
			}
		} // if((type & xOutConsol) != 0)
#endif
#if defined(_XTRACE_DBGCONSOLE)
		WChar wsz[256];
		
		if((type & eType_DbgConsol) != 0)
		{
			Bool ret = MByteToWChar(sz,wsz,256);
			if(ret)
				::OutputDebugStringW( wsz );
			//::OutputDebugStringA( sz );
		}
#endif
#if defined(_XTRACE_LOGFILE)
		if((type & eType_LogFile) != 0)
		{
			HANDLE file;
			file = CreateFileA(("trace.txt"),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			if(file != INVALID_HANDLE_VALUE)
			{
				//fwrite(sz,strlen(sz),1,_xlogfp);
				Uns32 written;
				::WriteFile(file,sz,(Uns32)strlen(sz),&written,vNull);
				::CloseHandle(file);
			} // if(file != INVALID_HANDLE_VALUE)
		} // if((type & xTraceType::xLogFile) != 0)
#endif
#if defined(_XTRACE_MSGBOX)
		if((type & eType_MsgBox) != 0)
		{ 
			MessageBoxA(vNull,sz,"trace",MB_OK);
		}
#endif
#if defined(_XTRACE_ASSERT)
		if((type & eType_DxAssert) != 0)
		{
#ifdef D3D9_INCLUDE
			DXTraceA(NULL,0,0,sz,vTrue);
#endif
		}
		else if((type & eType_AssertBox) != 0)
		{
			assert(0&&(char*)sz);
		}

#endif
		return ;
	}

	Void xTraceW(xTraceType type,Uns32 errLevel,const WChar* fmt,...)
	{
		WChar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfW(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceW(type,sz);
	}
	Result xTraceHrW(xTraceType type,Uns32 traceLevel,Result hr,const WChar* fmt,...)
	{
		WChar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfW(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceW(type,sz);
		return hr;
	}

	Void xTraceA(xTraceType type,Uns32 errLevel,const AChar* fmt,...)
	{
		AChar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfA(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceA(type,sz);
	}
	Result xTraceHrA(xTraceType type,Uns32 traceLevel,Result hr,const AChar* fmt,...)
	{
		AChar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfA(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceA(type,sz);
		return hr;
	}

#else
	Void	xTraceW(xTraceType type,Uns32 traceLevel,const Char* fmt,...)	{;}
	TResult xTraceHrW(xTraceType type,Uns32 traceLevel,TResult hr,const Char* fmt,...)	{return hr;}
	Void	xTraceA(xTraceType type,Uns32 traceLevel,const Char* fmt,...)	{;}
	TResult xTraceHrA(xTraceType type,Uns32 traceLevel,TResult hr,const Char* fmt,...)	{return hr;}
#endif

#pragma warning(default:4996)
}//NLib
